﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

using Common.TokenReader;
using Data.GameData;
using Data.GameData.Interfaces;
using Data.GameData.Utils;
using Data.GameData.GameMap;
using GameFramework;
using GameFramework.Orders;

namespace Tester
{
    class Program
    {
        const string filepath = @"D:\Projects\GAME\TokenReader\Data\";

        static void Main(string[] args)
        {
            //Framework.LoadGameDataFiles(filepath);

            DatabaseTest();
        }

        public static void DatabaseTest()
        {
            List<Game> gameList = Game.Games;
            Game.ActiveGame = gameList[1];

            //Race newRace = new Race("Cylon", Guid.NewGuid());
            //Race.AddNewRace(newRace);
            //Game.ActiveGame.Save();

            //StarSystem starSys = new StarSystem();
            //starSys.MapId = 1;
            //starSys.Type = StarSystemType.SINGLE;
            //starSys.Enviroment = StarSystemEnviroment.NORMAL;
                        //SystemBody sun = new SystemBody(starSys.Id, SystemBodyType.SUN, SystemBodyEnviroment.TYPE_O3, 3, 1, null);
            //starSys.AddSun(sun);
            //SystemBody body = new SystemBody(starSys.Id, SystemBodyType.PLANET, SystemBodyEnviroment.TYPE_T, 2, 5, sun);
            //starSys.AddBody(body);
            //starSys.Save();

            StarSystem dbStar = StarSystem.StarSystems.First();
            SystemBody dbSun = dbStar.Suns.FirstOrDefault();
            SystemBody dbBody = dbStar.Bodies.FirstOrDefault();

            Race race = Race.Races.First();
        }

        public static void MovementTest()
        {
            Fleet fleet = new Fleet { Name = "Test", Heading = 7, MapPosition = new MapIndex(1, 10, 10) };
           
            StarShip destroyer1 = new StarShip(GameDataStore.GetShipClass("DD"));
            StarShip destroyer2 = destroyer1.Clone() as StarShip;
            destroyer1.Parse("SSAHIaIaQaIaIaIa");
            destroyer2.Parse(destroyer1.ToString());

            fleet.AddFleetUnit(destroyer1);
            fleet.AddFleetUnit(destroyer2);

            for (int pulse = 1; pulse <= 6; ++pulse)
            {
                int hexes = MovementManager.HexesToMove(pulse, fleet);
            }
        }

        public static void TestOrders()
        {
            Game.ActiveGame = new Game("Test");
            Race race = new Race("Test", Guid.NewGuid());
            Race.AddNewRace(race);
            Race.ActiveRace = race;

            StarSystem starSys = new StarSystem();
            SystemBody star = new SystemBody(starSys.Id, SystemBodyType.SUN, SystemBodyEnviroment.TYPE_G, 3, 1, null);
            SystemBody homeWorld = new SystemBody(starSys.Id, SystemBodyType.PLANET, SystemBodyEnviroment.TYPE_T, 2, 5, star);
            SystemBody moon = new SystemBody(starSys.Id, SystemBodyType.MOON, SystemBodyEnviroment.TYPE_O2, 1, 2, homeWorld);

            Population homePop = new Population(homeWorld, race.Id, 2000);
            homeWorld.Population = homePop;
            race.AddPopulation( homePop);
            
            Unit shipyard = new Unit(new ShipClass(), UnitType.Starbase);
            shipyard.Name = "Prime SY";
            shipyard.ShipYard = new Shipyard();
            shipyard.MapPosition = new MapIndex(1, 10, 10);
            shipyard.OwnerId = race.Id;

            race.AddStarbase(shipyard);


            BuildUnitOrder bOrder = new BuildUnitOrder { UnitToBuild = new StarShip(new ShipClass()), ShipYard = shipyard };
            PlacePopulationOrder pOrder = new PlacePopulationOrder { Location = moon, StartPopulation = homePop, Quantity = 10 };
            race.AddOrder(bOrder);
            race.AddOrder(pOrder);

            foreach (IOrder order in race.Orders.Where(o => o.Status != OrderStatusType.COMPLETE))
            {
                order.Fulfill();
            }
            race.ClearCompletedOrders();

            MovementOrder mOrder = new MovementOrder { Unit = Race.ActiveRace.Fleets.First(), Destination = new MapIndex(1, 15, 15) };
            race.AddOrder(mOrder);

            foreach (IOrder order in race.Orders.Where(o => o.Status != OrderStatusType.COMPLETE))
            {
                order.Fulfill();
            }
            MapIndex dest = mOrder.Destination;
            race.ClearCompletedOrders();
        }

        #region Older Tests
        public static void TestPlanets()
        {
            List<int> orbits = SystemGeneration.CalculatePlanetaryOrbits();
            List<SystemBody> planets = new List<SystemBody>();

            StarSystem starSys = new StarSystem();

            SystemBody p;
            foreach (int o in orbits)
            {
                p = new SystemBody(starSys.Id, SystemBodyType.PLANET, SystemBodyEnviroment.TYPE_T, 1, o, null);
                SystemGeneration.DertermineEnviroment(StarType.WHITE_STAR, o, ref p);
                planets.Add(p);

                int moons = SystemGeneration.MoonCount(p.Mass, p.Enviroment);
            }
        }

        public static void TestMapDistances()
        {
            MapIndex start = new MapIndex(5, 35, 35);

            MapIndex end = Map.MapPositionFrom(start, 1, 25, true);

            MapIndex end1 = Map.MapPositionFrom(start, 1, 3, false);
            MapIndex end3 = Map.MapPositionFrom(start, 3, 3, false);
            MapIndex end5 = Map.MapPositionFrom(start, 5, 3, false);
            MapIndex end7 = Map.MapPositionFrom(start, 7, 3, false);
            MapIndex end9 = Map.MapPositionFrom(start, 9, 3, false);
            MapIndex end11 = Map.MapPositionFrom(start, 11, 3, false);

            MapIndex end2 = Map.MapPositionFrom(start, 2, 3, false);
            MapIndex end4 = Map.MapPositionFrom(start, 4, 3, false);
            MapIndex end6 = Map.MapPositionFrom(start, 6, 3, false);
            MapIndex end8 = Map.MapPositionFrom(start, 8, 3, false);
            MapIndex end10 = Map.MapPositionFrom(start, 10, 3, false);
            MapIndex end12 = Map.MapPositionFrom(start, 12, 3, false);

            int angle0 = Map.AngleTo(start, start);
            int angle1 = Map.AngleTo(start, end1);
            int angle3 = Map.AngleTo(start, end3);
            int angle5 = Map.AngleTo(start, end5);
            int angle7 = Map.AngleTo(start, end7);
            int angle9 = Map.AngleTo(start, end9);
            int angle11 = Map.AngleTo(start, end11);

            int dist1 = Map.DistanceTo(new MapIndex(5, 35, 35), new MapIndex(5, 33, 36));
            int dist2 = Map.DistanceTo(new MapIndex(5, 35, 34), new MapIndex(5, 34, 35));
        }

        public static void TestShipSystems()
        {
            Random rand = new Random();

            StarShip destroyer1 =
                new StarShip(GameDataStore.GetStoreContents("ShipClass").Find(ship => ship.ToString() == "DD") as ShipClass);
            StarShip destroyer2 =
                new StarShip(GameDataStore.GetStoreContents("ShipClass").Find(ship => ship.ToString() == "DD") as ShipClass);

            #region DD1 Systems
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "S").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "S").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "S").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "S").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "S").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "S").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "A").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "A").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "A").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "A").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "H").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "Ia").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("WeaponSystem").Find(sys => sys.ToString() == "Ga").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("WeaponSystem").Find(sys => sys.ToString() == "Ga").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "Ia").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "Qa").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "Ia").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "Ia").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("WeaponSystem").Find(sys => sys.ToString() == "Ga").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("WeaponSystem").Find(sys => sys.ToString() == "Ga").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "Ia").Clone() as ShipSystem);
            destroyer1.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "Qa").Clone() as ShipSystem);
            #endregion
            #region DD2 Systems
            destroyer2.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "S").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "S").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "S").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "S").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "A").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "A").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "A").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "H").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "Ia").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("WeaponSystem").Find(sys => sys.ToString() == "Ga").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("WeaponSystem").Find(sys => sys.ToString() == "Ga").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "Ia").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "Qa").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "Ia").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "Ia").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("WeaponSystem").Find(sys => sys.ToString() == "Ga").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("WeaponSystem").Find(sys => sys.ToString() == "Ga").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("WeaponSystem").Find(sys => sys.ToString() == "Ga").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "Ia").Clone() as ShipSystem);
            destroyer2.AddSystem(GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "Qa").Clone() as ShipSystem);
            #endregion

            ShipSystem system1 = GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "S").Clone() as ShipSystem;
            ShipSystem system2 = GameDataStore.GetStoreContents("ShipSystem").Find(sys => sys.ToString() == "S").Copy() as ShipSystem;

            int id1 = Map.CreateMap();
            int id2 = Map.CreateMap();

            destroyer1.MapPosition = new MapIndex(id1, 50, 50);
            destroyer2.MapPosition = new MapIndex(id1, 50, 45);

            int dist = Map.DistanceTo(destroyer1.MapPosition, destroyer2.MapPosition);
            Map.DeleteMap(id2);
        }
        #endregion
    }
}
